/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.xuexiang.xui_lib.stickycustom;

import ohos.agp.components.Component;
import ohos.agp.components.ListContainer;

import com.xuexiang.xui_lib.util.TextUtils;


/**
 * 粘顶滑动处理类
 *
 * @author gzc
 * @since 2021-04-28
 */
public class StickListScrollManager {
    /**
     * 通过SCROLLVIEW方式实现粘顶效果
     */
    public static final int STICKY_TYPE_NESTED_SCROLLVIEW = 0;
    /**
     * 通过DECORATION方式实现粘顶效果
     */
    public static final int STICKY_TYPE_DECORATION = 1;
    /**
     * 通过监听滑动方式实现粘顶效果
     */
    public static final int STICKY_TYPE_MONITOR_SCROLL_STATE = 2;
    private final Component mHeaderComponent;
    private final int mStickyType;
    private ListContainer mListContainer;
    private int mFirstVisiblePosition;
    private int mOffsetY = 0;
    private String mLastGroupName;
    private TitleChangeListener mListener;

    /**
     * 构造器
     *
     * @param listContainer
     * @param headerComponent 标题
     * @param stickyType 方式
     */
    public StickListScrollManager(ListContainer listContainer, Component headerComponent, int stickyType) {
        this.mListContainer = listContainer;
        this.mHeaderComponent = headerComponent;
        this.mStickyType = stickyType;
        initScrollState();

    }

    public void setTitleChangeListener(TitleChangeListener listener) {
        this.mListener = listener;
    }

    /**
     * 标题更改回调监听
     */
    public interface TitleChangeListener {
        /**
         * 标题更改回调
         *
         * @param title
         */
        void onTitleChangeCallback(String title);
    }

    public void setHeaderComponentOffsetY(int offsetY) {
        this.mOffsetY = offsetY;
    }



    private void initScrollState() {
        if (mStickyType == STICKY_TYPE_MONITOR_SCROLL_STATE) {
            mListContainer.setScrolledListener(new Component.ScrolledListener() {
                @Override
                public void onContentScrolled(Component component, int i, int i1, int i2, int i3) {
                    handlerListScroll();
                }
            });
        }
    }


    private void handlerListScroll() {
        try {
            int mTitleHeight = mHeaderComponent.getEstimatedHeight();
            int firstPosition = mListContainer.getItemPosByVisibleIndex(0);
            Component firstVisibleComponent = mListContainer.getComponentAt(firstPosition);
            float topY = firstVisibleComponent.getTop();
            int firstCompletePosition = getFirstCompletelyVisibleItemPosition(firstPosition, topY);
            StickyDataCategory firstVisibleData = (StickyDataCategory) mListContainer.getItemProvider().getItem(firstPosition);
            StickyDataCategory firstCompleteVisibleData = (StickyDataCategory) mListContainer.getItemProvider().getItem(firstCompletePosition);
            if (firstCompletePosition > 0 && firstCompletePosition < mListContainer.getChildCount()
                && firstCompleteVisibleData.isHeadSticky()) {
                //当前完全可见的第一个item条目，并且是需要吸顶的item
                Component firstCompleteVisibleComponent = mListContainer.getComponentAt(firstCompletePosition);
                if (firstCompleteVisibleComponent != null && firstCompleteVisibleComponent.getTop() <= mTitleHeight) {
                    //当前完全可见的第一个item条目的y坐标进入标题区域时，动态设置y坐标
                    if (firstPosition != firstCompletePosition) {
                        mHeaderComponent.setContentPositionY(firstCompleteVisibleComponent.getTop() - mTitleHeight + mOffsetY);
                    }
                }
            }
            if (mFirstVisiblePosition != firstPosition && firstPosition >= 0) {
                mFirstVisiblePosition = firstPosition;
                mHeaderComponent.setContentPositionY(mOffsetY);
                String currentGroupName = firstVisibleData.isHeadSticky()
                    ? firstVisibleData.getHeadTitle()
                    : findStickyHeadName(firstPosition);
                if (TextUtils.isEmpty(mLastGroupName) || !mLastGroupName.equals(currentGroupName)) {
                    mLastGroupName = currentGroupName;
                    if (mListener != null) {
                        mListener.onTitleChangeCallback(mLastGroupName);
                    }
                }

            }
        } catch (Exception exception) {

        }
    }

    /**
     * 从传入位置递减找出标签的位置
     *
     * @param startPosition 开始寻找的位置
     * @return 最近的一个标签的位置
     */
    private String findStickyHeadName(int startPosition) {
        for (int position = startPosition; position >= 0; position--) {
            // 位置递减，只要查到位置是标签，立即返回此位置
            StickyDataCategory stickyItem = (StickyDataCategory) mListContainer.getItemProvider().getItem(position);
            if (stickyItem.isHeadSticky()) {
                return stickyItem.getHeadTitle();
            }
        }
        return "";
    }


    private int getFirstCompletelyVisibleItemPosition(int firstVisibleIndex, float positionY) {
        if (positionY == 0) {
            return firstVisibleIndex;
        } else {
            return firstVisibleIndex + 1;
        }
    }
}
